package cn.aimee.permission.ui.activity;

import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.Gravity;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import cn.aimee.permission.ui.dialog.CustomTipDialog;
import cn.aimee.permission.util.permission.PermissionDescriptionUtil;
import cn.aimee.permission.util.string.StringUtil;

public class PermissionBaseActivity extends AppCompatActivity {

    /**从应用信息界面返回*/
    public static final int REQUEST_CODE_APP_SETTING = 1000;
    /**是否请求获取权限请求了两次*/
    public boolean isRequestPermissionTwice = false;

    private Context mPermissionContext;
    private CustomTipDialog goToSetPermissionDialog;
    private CustomTipDialog goToSetGPSDialog;
    private OnPermissionResultListener mOnPermissionResultListener;

    private static final int REQUEST_PERMISSION = 1001;
    private static final int REQUEST_PERMISSIONS = 10002;
    private String message;
    private boolean isCanRequestPermission = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPermissionContext = this;
        isCanRequestPermission = true;
        isRequestPermissionTwice = false;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        dismissGoToSetPermissionDialog();
        dismissGoToSetGPSDialog();
    }

    public interface OnPermissionResultListener {
        /**
         * 当Android版本高于或等于23版本，即权限申请成功后，才执行此方法中的内容
         * 当Android版本低于23版本，将不进行权限申请，直接执行此方法中的内容
         */
        public void onPermissionGranted();

        /**
         * 权限申请失败
         */
        public void onPermissionDenied();
    }

    private void onGranted() {
        if (null != mOnPermissionResultListener)
            mOnPermissionResultListener.onPermissionGranted();
    }

    private void onDenied() {
        if (null != mOnPermissionResultListener)
            mOnPermissionResultListener.onPermissionDenied();
    }

    /**
     * 获取单个权限
     * @param permission
     */
    public void checkPermission(String permission, OnPermissionResultListener onPermissionResultListener) {
        isRequestPermissionTwice = false;
        mOnPermissionResultListener = onPermissionResultListener;
        checkPermission(permission, PermissionDescriptionUtil.get(mPermissionContext, permission));
    }

    private void checkPermission(String permission, String message) {
        this.message = message;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(mPermissionContext, permission) == PackageManager.PERMISSION_DENIED) {
                if (!isCanRequestPermission) {
                    return;
                }
                isCanRequestPermission = false;
                ActivityCompat.requestPermissions(this,
                        new String[]{permission}, REQUEST_PERMISSION);
            } else {
                dismissGoToSetPermissionDialog();
                onGranted();
            }
        } else {
            dismissGoToSetPermissionDialog();
            onGranted();
        }
    }

    public void checkPermissions(String[] permissionsStr, OnPermissionResultListener onPermissionResultListener) {
        isRequestPermissionTwice = false;
        mOnPermissionResultListener = onPermissionResultListener;
        checkPermissions(permissionsStr);
    }

    private void checkPermissions(String[] permissionsStr) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            List<String> deniedPermissionList = new ArrayList<>();
            for (int i = 0; i < permissionsStr.length; i++) {
                if (ContextCompat.checkSelfPermission(mPermissionContext, permissionsStr[i]) !=
                        PackageManager.PERMISSION_GRANTED) {
                    deniedPermissionList.add(permissionsStr[i]);
                }
            }
            if (deniedPermissionList.isEmpty()) {
                onGranted();
            } else {
                String[] permissions = deniedPermissionList.toArray(new String[deniedPermissionList.size()]);
                ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSIONS);
            }
        } else {
            onGranted();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (null != goToSetPermissionDialog && goToSetPermissionDialog.isShowing()) {
            return;
        }
        if (requestCode == REQUEST_PERMISSION) {
            handleSinglePermissionResult(permissions, grantResults);
        } else if (requestCode == REQUEST_PERMISSIONS) {
            handlePermissionsResult(permissions, grantResults);
        }
    }

    /**
     * 处理单个权限申请的回调结果
     * @param permissions
     * @param grantResults
     */
    private void handleSinglePermissionResult(String[] permissions, int[] grantResults) {
        if (grantResults.length == 0) {
            isCanRequestPermission = true;
            return;
        }
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            dismissGoToSetPermissionDialog();
            onGranted();
            isCanRequestPermission = true;
        } else {
            showGoToSetPermissionDialog(message, permissions);
        }
    }

    /**
     * 处理多个权限申请的回调结果
     * @param permissions
     * @param grantResults
     */
    private void handlePermissionsResult(String[] permissions, int[] grantResults) {
        List<String> deniedList = new ArrayList<>();
        for (int i=0; i<permissions.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                if (!deniedList.contains(permissions[i])) {
                    if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permissions[i])) {
                        if (!deniedList.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                            deniedList.add(permissions[i]);
                        }
                    } else if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permissions[i])) {
                        if (!deniedList.contains(Manifest.permission.READ_EXTERNAL_STORAGE)) {
                            deniedList.add(permissions[i]);
                        }
                    } else if (Manifest.permission.ACCESS_FINE_LOCATION.equals(permissions[i])) {
                        if (!deniedList.contains(Manifest.permission.ACCESS_COARSE_LOCATION)) {
                            deniedList.add(permissions[i]);
                        }
                    } else if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permissions[i])) {
                        if (!deniedList.contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
                            deniedList.add(permissions[i]);
                        }
                    }else {
                        deniedList.add(permissions[i]);
                    }
                }
            }
        }
        if (deniedList.isEmpty()) {
            dismissGoToSetPermissionDialog();
            onGranted();
        } else {
            message = PermissionDescriptionUtil.gets(mPermissionContext,
                    deniedList.toArray(new String[deniedList.size()]));
            showGoToSetPermissionDialog(message, deniedList.toArray(new String[deniedList.size()]));
        }
    }

    public void showGoToSetPermissionDialog(String message, final String[] deniedPermissions) {
        showGoToSetPermissionDialog(message, deniedPermissions,null);
    }

    /**
     * 当用户禁止了权限申请，会弹出提示用户去设置权限
     * @param message
     * @param deniedPermissions
     * @param onPositiveClickListener
     */
    public void showGoToSetPermissionDialog(String message, final String[] deniedPermissions,
                                            DialogInterface.OnClickListener onPositiveClickListener) {
        // 在一个功能点处请求了两次权限申请，就不弹出此框
        if (isRequestPermissionTwice) {
            isCanRequestPermission = true;
            onDenied();
            return;
        }
        if (StringUtil.isEmpty(message)) {
            dismissGoToSetPermissionDialog();
            onDenied();
            isCanRequestPermission = true;
            return;
        }
        if (goToSetPermissionDialog != null && goToSetPermissionDialog.isShowing()) {
            return;
        }
        CustomTipDialog.Builder builder = new CustomTipDialog.Builder(this);
        builder.setMessage(message, Gravity.NO_GRAVITY)
                .setNegativeButton(null, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        onDenied();
                    }
                });

        if (onPositiveClickListener == null) {
            builder.setPositiveButton(cn.aimee.permission.R.string.str_to_set, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    goToSet(deniedPermissions);
                }
            });
        } else {
            builder.setPositiveButton(cn.aimee.permission.R.string.str_to_set, onPositiveClickListener);
        }
        goToSetPermissionDialog = builder.create();
        goToSetPermissionDialog.setCancelable(false);
        goToSetPermissionDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                isCanRequestPermission = true;
            }
        });
        goToSetPermissionDialog.show();
    }

    private void dismissGoToSetPermissionDialog() {
        if(null != goToSetPermissionDialog && goToSetPermissionDialog.isShowing()) {
            goToSetPermissionDialog.dismiss();
        }
    }

    private void dismissGoToSetGPSDialog() {
        if(null != goToSetGPSDialog && goToSetGPSDialog.isShowing())
            goToSetGPSDialog.dismiss();
    }

    /**
     * 去设置
     * @param deniedPermissions
     */
    private void goToSet(String[] deniedPermissions) {
        dismissGoToSetPermissionDialog();
        if (null == deniedPermissions || deniedPermissions.length == 0) {
            isRequestPermissionTwice = false;
            startAppSettingActivity();
        } else {
            boolean isCanShow = false;
            for (int i=0; i<deniedPermissions.length; i++) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(
                        PermissionBaseActivity.this, deniedPermissions[i])) {
                    isCanShow = true;
                    break;
                }
            }
            if (isCanShow) {
                isRequestPermissionTwice = true;
                checkPermissions(deniedPermissions);
            } else {
                isRequestPermissionTwice = false;
                startAppSettingActivity();
            }
        }
    }

    /**
     * 进入应用信息设置界面
     */
    private void startAppSettingActivity() {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent, REQUEST_CODE_APP_SETTING);
    }

}